/******************************************************************************
//             INTEL CORPORATION PROPRIETARY INFORMATION
//  This software is supplied under the terms of a license agreement or
//  nondisclosure agreement with Intel Corporation and may not be copied
//  or disclosed except in accordance with the terms of that agreement.
//    Copyright(c) 2001 Intel Corporation. All Rights Reserved.
//
//  VSS: 
//     $Workfile: $
//     $Revision: $
//     $Date:     $
//     $Archive:  $
//
//  Description:
//
//  History:
//     Date        Author        Changes
//     2001/8/7   Jerry Hu       Created  (Version 0.1)
//
********************************************************************************/

#include <stdio.h>
#include <stdlib.h>

#include "impbase.h"
#include "ijx.h"

#include "dib.h"

///////////////////////////////////////////////////////////////////////////////
// DestoryDIB
void DestoryDIB(MDIBSPEC *pDIBSpec)
{
    if (pDIBSpec->pBitmapData) {
        free(pDIBSpec->pBitmapData);
    }
    pDIBSpec->nBitsPerpixel=0;
    pDIBSpec->nClrMode=0;
    pDIBSpec->nDataSize=0;
    pDIBSpec->nHeight=0;
    pDIBSpec->nNumComponent=0;
    pDIBSpec->nPrecision=0;
    pDIBSpec->nStep=0;
    pDIBSpec->nWidth=0;
    pDIBSpec->pBitmapData=0;
}

///////////////////////////////////////////////////////////////////////////////
// ReadDIBFile
int ReadDIBFile(MDIBSPEC *pDIBSpec, FILE *file)
{
    Ipp8u   anData8[16];
    Ipp16u  data16;
    Ipp16u  data16i;
    Ipp32u  data32;
    Ipp32u  bfSize;    
    Ipp32u  bfOffBits;
    Ipp32u  biCompression;
    Ipp32u  anMask[3];

    /* Read DIB Header information */
    
    /* bfType - 2;             */
    if ( (fread(anData8, 1, 2, file)!=2)||(anData8[0]!='B')||(anData8[1]!='M') ) {
        return FALSE;
    }

    /* bfSize - 4;             */
    if ( (fread(&bfSize, 4, 1, file)!=1) ) {
        return FALSE;
    }

    /* bfReserved1 - 2;        */
    /* bfReserved2 - 2;        */
    fseek(file, 4, SEEK_CUR);

    /* bfOffBits - 4;          */
    if ( (fread(&bfOffBits, 4, 1, file)!=1) ) {
        return FALSE;
    }

    /* BITMAPINFOHEADER */
 ftell(file);
    /* biSize - 4 */
    if ( (fread(&data32, 4, 1, file)!=1)||(0==data32) ) {
        return FALSE;
    }

    /* biWidth - 4 */
    if ( (fread(&data32, 4, 1, file)!=1)||(0==data32) ) {
        return FALSE;
    }
    pDIBSpec->nWidth=data32;

    /* biHeight - 4 */
    if ( (fread(&data32, 4, 1, file)!=1)||(0==data32) ) {
        return FALSE;
    }
    pDIBSpec->nHeight=data32;

    /* biPlanes - 2 */
    if ( fread(&data16, 2, 1, file)!=1 ) {
        return FALSE;
    }

    /* biBitCount - 2 */
    if ( (fread(&data16, 2, 1, file)!=1) ) {
        return FALSE;
    }
    pDIBSpec->nBitsPerpixel=data16;

    pDIBSpec->nStep     = IIP_WIDTHBYTES_4B((pDIBSpec->nWidth)*(pDIBSpec->nBitsPerpixel));
    pDIBSpec->nDataSize = pDIBSpec->nStep*pDIBSpec->nHeight;

    /* Allocate memory for bitmap data */
	pDIBSpec->pBitmapData = (Ipp8u *) malloc(pDIBSpec->nDataSize);
    if (!pDIBSpec->pBitmapData) {
		return FALSE;
	}

    /* biCompression - 4 */
    if ( (fread(&biCompression, 4, 1, file)!=1) ) {
        return FALSE;
    }

    if ( (BI_RGB!=biCompression) && (BI_BITFIELDS!=biCompression) ) {
        return FALSE;
    }

    /* biSizeImage - 4 */
    if ( (fread(&data32, 4, 1, file)!=1)||(0==data32) ) {
        return FALSE;
    }

    /* biXPelsPerMeter - 4 */
    if ( fread(&data32, 4, 1, file)!=1 ) {
        return FALSE;
    }

    /* biYPelsPerMeter - 4 */
    if ( fread(&data32, 4, 1, file)!=1 ) {
        return FALSE;
    }

    /* biClrUsed - 4 */
    if ( fread(&data32, 4, 1, file)!=1 ) {
        return FALSE;
    }

    /* biClrImportant - 4 */
    if ( fread(&data32, 4, 1, file)!=1 ) {
        return FALSE;
    }
    
    /* Get Color Mode */
    switch (pDIBSpec->nBitsPerpixel) {
        case 8:
            pDIBSpec->nNumComponent=1;
            pDIBSpec->nPrecision=8;
            pDIBSpec->nClrMode=IIP_CM_GRAY;
            break;
        case 24:
            pDIBSpec->nNumComponent=3;
            pDIBSpec->nPrecision=8;
            pDIBSpec->nClrMode=IIP_CM_BGR;
            break;
        case 16:
            pDIBSpec->nNumComponent=3;
            pDIBSpec->nPrecision=8;
            if ( BI_BITFIELDS==biCompression ) {
                if ( fread(&anMask, 4, 3, file)!=3 ) {
                    return FALSE;
                }
                if ( (0x001F==anMask[0])||(0x03E0==anMask[1])||(0x7C00==anMask[2]) ) {
                    pDIBSpec->nClrMode=IIP_CM_BGR555;
                } else if ( (0x001F==anMask[0])||(0x07E0==anMask[1])||(0xF800==anMask[2]) ) {
                    pDIBSpec->nClrMode=IIP_CM_BGR565;
                } else {
                    return FALSE;
                }
            }
            break;
        default:
            return FALSE;
    }

    //data32=ftell(file);

    fseek(file, bfOffBits, SEEK_SET);

    data32 = fread(pDIBSpec->pBitmapData, 1, pDIBSpec->nDataSize, file);

    fseek(file, 0, SEEK_END);

    if (  data32 != (Ipp32u)(pDIBSpec->nDataSize) ) {
        return FALSE;
    }

    return TRUE;
}


///////////////////////////////////////////////////////////////////////////////
// WriteDIBFile
int WriteDIBFile(MDIBSPEC *pDIBSpec, FILE *file)
{
    Ipp8u   anData8[16];
    Ipp16u  data16;
    Ipp32u  data32;
    Ipp32u  bfSize;    
    Ipp32u  bfOffBits;
    Ipp32u  biCompression;
    Ipp32u  anMask[3];

    /* Read DIB Header information */
    
    /* bfType - 2;             */
    anData8[0] = 'B';
    anData8[1] = 'M';
    if ( (fwrite(&anData8, 1, 2, file)!=2) ) {
        return FALSE;
    }
    /* bfSize - 4;             */
    if ( (fwrite(&bfSize, 4, 1, file)!=1) ) {
        return FALSE;
    }

    /* bfReserved1 - 2;        */
    /* bfReserved2 - 2;        */
    fseek(file, 4, SEEK_CUR);

    /* bfOffBits - 4;          */
    if ( (fwrite(&bfOffBits, 4, 1, file)!=1) ) {
        return FALSE;
    }

    /* BITMAPINFOHEADER */

    /* biSize - 4 */
    data32 = 40;
    if ( (fwrite(&data32, 4, 1, file)!=1) ) {
        return FALSE;
    }

    /* biWidth - 4 */
    data32=pDIBSpec->nWidth;
    if ( (fwrite(&data32, 4, 1, file)!=1) ) {
        return FALSE;
    }

    /* biHeight - 4 */
    data32=pDIBSpec->nHeight;
    if ( (fwrite(&data32, 4, 1, file)!=1) ) {
        return FALSE;
    }

    /* biPlanes - 2 */
    data16=1;
    if ( fwrite(&data16, 2, 1, file)!=1 ) {
        return FALSE;
    }

    /* biBitCount - 2 */
    data16=(Ipp16u)pDIBSpec->nBitsPerpixel;
    if ( (fwrite(&data16, 2, 1, file)!=1) ) {
        return FALSE;
    }

    /* biCompression - 4 */
    biCompression = ((IIP_CM_BGR555|IIP_CM_BGR565)&pDIBSpec->nClrMode) ? BI_BITFIELDS : BI_RGB;
    if ( fwrite(&biCompression, 4, 1, file)!=1 ) {
        return FALSE;
    }

    /* biSizeImage - 4 */
    data32 = pDIBSpec->nDataSize;
    if ( (fwrite(&data32, 4, 1, file)!=1) ) {
        return FALSE;
    }

    /* biXPelsPerMeter - 4 */
    data32 = 72;
    if ( fwrite(&data32, 4, 1, file)!=1 ) {
        return FALSE;
    }

    /* biYPelsPerMeter - 4 */
    data32 = 72;
    if ( fwrite(&data32, 4, 1, file)!=1 ) {
        return FALSE;
    }

    /* biClrUsed - 4 */
    data32 = 0;
    if ( fwrite(&data32, 4, 1, file)!=1 ) {
        return FALSE;
    }

    /* biClrImportant - 4 */
    data32 = 0;
    if ( fwrite(&data32, 4, 1, file)!=1 ) {
        return FALSE;
    }
    
    /* Get Color Mode */
    if (IIP_CM_BGR555==pDIBSpec->nClrMode) {
        anMask[2]=0x001F;
        anMask[1]=0x03E0;
        anMask[0]=0x7C00;
        if ( fwrite(&anMask, 4, 3, file)!=3 ) {
            return FALSE;
        }
    } else if (IIP_CM_BGR565==pDIBSpec->nClrMode) {
        anMask[2]=0x001F;
        anMask[1]=0x07E0;
        anMask[0]=0xF800;
        if ( fwrite(&anMask, 4, 3, file)!=3 ) {
            return FALSE;
        }
    }

    /* bfOffBits -4 */
    data32=ftell(file);
    fseek(file, 10, SEEK_SET);
    if ( fwrite(&data32, 4, 1, file)!=1 ) {
        return FALSE;
    }

    fseek(file, data32, SEEK_SET);

    data32 = fwrite(pDIBSpec->pBitmapData, 1, pDIBSpec->nDataSize, file);

    if (  data32 != (Ipp32u)(pDIBSpec->nDataSize) ) {
        return FALSE;
    }

    /* bfOffBits -4 */
    data32=ftell(file);
    fseek(file, 2, SEEK_SET);
    if ( fwrite(&data32, 4, 1, file)!=1 ) {
        return FALSE;
    }

    fseek(file, 0, SEEK_END);
    return TRUE;
}

/* EOF */
